/**
 * Created by Administrator on 2017/1/16.
 */

var MJPlayer = require('../MJ/player').MJPlayer;
var MJ = require('../MJ/MJ');
var Const = require('./const');
var SubCode = require('../subCode');

exports.QZMJPlayer = MJPlayer.extend({
    _selectMAI : 0,
    isDianPao: false,
    mode50: 0,
    youjin : 0,
    _selectCard: 0,
    _youjin : false,
    _ftgd: [],
    _roundFan: 0,
    _readyTimer : 0,
    init: function(uid, msg) {
        this._super(uid, msg);

        this._stat.zmCount = 0;             // 自摸次数
        this._stat.dpCount = 0;             // 点炮次数
        this._stat.dhCount = 0;             // 点胡次数
        this._stat.anGangCount = 0;        // 暗杠次数
        this._stat.mingGangCount = 0;      // 明杠次数
        this._stat.roundanGang = 0;        // 本轮暗杠次数
        this._stat.roundmingGang = 0;      // 本轮明杠次数
        this._stat.failCount = 0;           // 本轮失败次数

        this._ftgd = [];
        this._stat.lzCount = 0;             // 庄家次数
        this._stat.roundRules = {};         //规则`
        this._selectMAI = -1;                //选择买不买-1/0/1 未选择/不买/买
        this.youjin = 0;                //游金的单牌
        this._youjin = false;                //玩家是否游金
        this.isDianPao = false;
        this._selectCard = 0;
        this._readyTimer = 0;
        this._stat._huaCards = [];           //花牌
        this._stat.bifan = 0;           //比番
        this._roundFan = 0;
        this.mode50 = 50;

    },

   isMAI: function() {
        return this._selectMAI == 1;
    },

    isMAISelected: function() {
        return this._selectMAI != -1;
    },
    settlementGangScore: function() {
        var player = this;
        var room = this.getRoom();

        /*if (!this.isRoundHu()) {
            return;
        }*/
        for (var i = 0, l = this._gangCards.length; i < l; ++i) {
            var gangInfo = this._gangCards[i];

            if (gangInfo.gang == MJ.Gang.AN || gangInfo.gang == MJ.Gang.ANS) {
                this._stat.roundanGang++;
            } else {
                this._stat.roundmingGang++;
            }

        }
        var totalGangScore = (this._stat.roundanGang * 2) + this._stat.roundmingGang;
        player.addRoundGangScore(totalGangScore);
    },
    settlementPatternScore: function(){
        if (!this.isRoundHu()) {
            return;
        }
        var room = this.getRoom();
        var player = this;
        if(this._stat.roundPattern){

        }
        var score = 0;
        var maiscore = 0;
        var PatternScore = player.getRoundPatternScore();
        if(PatternScore == 1){
            score += 5;
            maiscore = 1;

        }else if(PatternScore == 2){
            score += 10;
            maiscore = 2;

        }else if(PatternScore == 3){
            score += 20;
            maiscore = 4;

        }
        room.enumPlayers(function(eIndex, ePlayer) {
            if (eIndex == player.getIndex()) {
                return;
            }
            if(player._stat.roundResult == MJ.Result.ZM || room.getOption('FHSP')) {
                ePlayer.addRoundScore(-score);
                player.addRoundScore(score);
                if (player._selectMAI > 0) {
                    ePlayer.addRoundScore(-maiscore);
                    player.addRoundScore(maiscore);
                }
                if (ePlayer._selectMAI > 0) {
                    ePlayer.addRoundScore(-maiscore);
                    player.addRoundScore(maiscore);
                }
            }else if(eIndex == room.getFirstDPIndex()) {
                ePlayer.addRoundScore(-score);
                player.addRoundScore(score);
                if (player._selectMAI > 0) {
                    ePlayer.addRoundScore(-maiscore);
                    player.addRoundScore(maiscore);
                }
                if (ePlayer._selectMAI > 0) {
                    ePlayer.addRoundScore(-maiscore);
                    player.addRoundScore(maiscore);
                }
            }else{
                if (player._selectMAI > 0) {
                    ePlayer.addRoundScore(-maiscore);
                    player.addRoundScore(maiscore);
                }
                if (ePlayer._selectMAI > 0) {
                    ePlayer.addRoundScore(-maiscore);
                    player.addRoundScore(maiscore);
                }
            }
        });
    },
    settlementPatternScore50: function() {
        var room = this.getRoom();
        var player = this;
        var subConfig = room.getSubConfig();
        //计算杠分
        var gangscre = this._stat.roundGangScore;
        var rule = Const.ScoreRule.GANG;
        player.addRoundItemScores(rule, gangscre);
        player.setRoundScoreRule(rule);
        //计算金分
        var jinscre = 0;
        jinscre = room.getBaoCardNum(player);
        /*if(this._stat.roundPattern != Const.Pattern.SANJIN){
        }*/
        rule = Const.ScoreRule.JIN;
        player.addRoundItemScores(rule, jinscre);
        player.setRoundScoreRule(rule);
        //计算花分
        var huascre = 0;
        if(this._stat.roundPattern != Const.Pattern.EIGHTHUA) {
            huascre = Math.floor(player._stat._huaCards.length / 4);

            var huaObj = {};
            for (var i = 0; i < player._stat._huaCards.length; i++) {
                ExObject.addNumber0(huaObj, player._stat._huaCards[i], 1)
            }

            //春夏秋冬
            var re = true;
            for (var i = MJ.getValue(MJ.Color.HUA, 1); i <= MJ.getValue(MJ.Color.HUA, 4); i++) {
                if (!huaObj[i]) {
                    re = false;
                    break;
                }
            }
            if (re) {
                huascre += 1;
            }
            //梅兰竹菊
            re = true;

            for (var i = MJ.getValue(MJ.Color.HUA, 5); i <= MJ.getValue(MJ.Color.HUA, 8); i++) {
                if (!huaObj[i]) {
                    re = false;
                    break;
                }
            }
            if (re) {
                huascre += 1;
            }
        }
        rule = Const.ScoreRule.HUA;
        player.addRoundItemScores(rule, huascre);
        player.setRoundScoreRule(rule);
        if(player.getIndex() == room.getDealerIndex()){
            rule = Const.ScoreRule.DEALER;
            player.addRoundItemScores(rule, Const.ItemScore[rule]);
            player.setRoundScoreRule(rule);
        }else {
            rule = Const.ScoreRule.XIAN;
            player.addRoundItemScores(rule, Const.ItemScore[rule]);
            player.setRoundScoreRule(rule);
        }
        this._roundFan = huascre + jinscre + gangscre;
        if (this.isRoundHu()) {

            var PatternScore = 0;

            PatternScore = player.getRoundPatternScore();

            //银家底分
            var score = huascre + jinscre + gangscre;
            //score += PatternScore;
            // 结算牌型及基础分
            if(player.getIndex() == room.getDealerIndex()){
                score += 8;
                score *= PatternScore;
                room.enumPlayers(function(eIndex, ePlayer) {
                    if (eIndex == player.getIndex()) {
                        return;
                    }
                    var maiscore = Const.ItemScore[player._stat.roundPattern];
                    if(player._stat.roundResult == MJ.Result.ZM || room.getOption('FHSP')){
                        ePlayer.addRoundScore(-score);
                        player.addRoundScore(score);
                        if(player._selectMAI > 0){
                            ePlayer.addRoundScore(-maiscore);
                            player.addRoundScore(maiscore);
                        }
                        if(ePlayer._selectMAI > 0){
                            ePlayer.addRoundScore(-maiscore);
                            player.addRoundScore(maiscore);
                        }
                    }else{
                        if(eIndex == room.getFirstDPIndex()){
                            ePlayer.addRoundScore(-score);
                            player.addRoundScore(score);
                            if(player._selectMAI > 0){
                                ePlayer.addRoundScore(-maiscore);
                                player.addRoundScore(maiscore);
                            }
                            if(ePlayer._selectMAI > 0){
                                ePlayer.addRoundScore(-maiscore);
                                player.addRoundScore(maiscore);
                            }
                        }
                    }

                });
            }else {
                room.enumPlayers(function(eIndex, ePlayer) {
                    var curscore = score;
                    if (eIndex == player.getIndex()) {
                        return;
                    }
                    if(eIndex == room.getDealerIndex()){
                        curscore += 8;
                    }else {
                        curscore += 4;
                    }
                    curscore *= PatternScore;

                    var maiscore = Const.ItemScore[player._stat.roundPattern];
                    if(player._stat.roundResult == MJ.Result.ZM || room.getOption('FHSP')){
                        ePlayer.addRoundScore(-curscore);
                        player.addRoundScore(curscore);
                        if(player._selectMAI > 0){
                            ePlayer.addRoundScore(-maiscore);
                            player.addRoundScore(maiscore);
                        }
                        if(ePlayer._selectMAI > 0){
                            ePlayer.addRoundScore(-maiscore);
                            player.addRoundScore(maiscore);
                        }
                    }else{
                        if(eIndex == room.getFirstDPIndex()){
                            ePlayer.addRoundScore(-curscore);
                            player.addRoundScore(curscore);
                            if(player._selectMAI > 0){
                                ePlayer.addRoundScore(-maiscore);
                                player.addRoundScore(maiscore);
                            }
                            if(ePlayer._selectMAI > 0){
                                ePlayer.addRoundScore(-maiscore);
                                player.addRoundScore(maiscore);
                            }
                        }
                    }
                });
            }
        }else {
            room.enumPlayers(function(eIndex, ePlayer) {
                if (eIndex == player.getIndex()) {
                    return;
                }
                if (eIndex == room.getFirstHuPlayerIndex()) {
                    return;
                }
                var ruleScore = huascre + jinscre + gangscre;
                ePlayer.addRoundScore(-ruleScore);
                player.addRoundScore(ruleScore);

            });
        }
        /*ExObject.eachKeyNum(this._stat.roundRules, function(rule, value) {
            player.addRoundItemScores(rule, Const.ItemScore[rule]);
            player.setRoundScoreRule(rule);
        });*/


    },

    /**
     * 结算点炮全包
     * @param dpPlayer
     */
    settlementDPQBScore: function(dpPlayer) {
        if (!this.isRoundTing()) {
            return;
        }

        var player = this;
        var room = this.getRoom();

        var otherMenQingCount = 0;
        room.enumPlayers(function(eIndex, ePlayer) {
            if (eIndex != player.getIndex() && ePlayer._stat.roundRules[Const.ScoreRule.MenQing]) {
                otherMenQingCount++;
            }
        });

        if (otherMenQingCount + 1 == room.getMaxPlayer()) {
            if (player._stat.roundRules[Const.ScoreRule.MenQing]) {
                delete player._stat.roundRules[Const.ScoreRule.MenQing];
                player._stat.roundRules[Const.ScoreRule.SiJiaQing] = 1;
            } else {
                player._stat.roundRules[Const.ScoreRule.SanJiaQing] = 1;
            }
        }

        ExObject.each(this._stat.roundRules, function(rule, value) {
            player.addRoundItemScores(rule, Const.ItemScore[rule]);
            player.setRoundScoreRule(rule);
        });

        // 结算牌型及基础分
        var basicFan = Const.PatternScore[this.getRoundPattern()] + ExObject.sumValue(this._stat.roundItemScores);
        basicFan = Math.min(room.getOption("FAN"), basicFan);
        if (basicFan < 1) {
            return;
        }

        var target = dpPlayer;
        var allExFan = 0;
        if (target.isBaoTing()) {
            var exFan = Const.ItemScore[Const.ScoreRule.BT];
            allExFan += exFan;
            target.addRoundScoreDetail(Const.ScoreReason.BT, -exFan);
        }

        if (target.isDealer()) {
            var exFan = Const.ItemScore[Const.ScoreRule.LZ];
            allExFan += exFan;
            target.addRoundScoreDetail(Const.ScoreReason.LZ, -exFan);
        }

        target.addRoundScoreDetail(player.getRoundResult(), -basicFan);

        var score = Math.pow(2, basicFan + allExFan - 1);
        target.addRoundScore(-score);
        player.addRoundScore(score);

    },

    settlementRules: function() {
        var rules = this._stat.roundRules;
        var room = this.getRoom();
        var player = this;

        /*if (!this.isRoundHu()) {
            return;
        }*/
        // 判断 清一色/混一色
        /*var colors = {};
        var existSpecGang = false;
        var existAnGang = false;
        if(this.isBaohu()){
            ExObject.eachKeyNum(this._handCards.getCards(), function(card, num) {
                if(card != room.baoCard){
                    colors[MJ.getColor(card)] = 1;
                }
            });
        }else{
            ExObject.eachKeyNum(this._handCards.getCards(), function(card, num) {
                colors[MJ.getColor(card)] = 1;
            });

        }
        if(this._stat.huCard != room.baoCard)
            colors[MJ.getColor(this._stat.huCard)] = 1;

        this._pengCards.forEach(function (card) {
            colors[MJ.getColor(card)] = 1;
        });

        this._chiCards.forEach(function(chiInfo) {
            colors[MJ.getColor(chiInfo.card)] = 1;
        });

        this._gangCards.forEach(function (gangInfo) {
            if (gangInfo.type) {
                existSpecGang = true;
            } else {
                if (gangInfo.gang == MJ.Gang.AN || gangInfo.gang == MJ.Gang.ANS) {
                    existAnGang = true;
                }
                colors[MJ.getColor(gangInfo.card)] = 1;
            }
        });
        var colorNum = Object.keys(colors).length;
        if (colorNum == 1) {
            rules[Const.ScoreRule.QingYiSe] = 1;
        }*/

        //花分
        /*
        var huafan = this._stat._huaCards.length / 4;
        if(huafan == 1){
            rules[Const.ScoreRule.QingYiSe] = 1;
        }
        */
        //杠分

    },
    settlement: function() {
        //this.addRoundScore(this._stat.roundGangScore);
        //this.addRoundScore(this._stat.roundPiaoScore);

        var room = this.getRoom();
        var player = this;

        /*for (var i = 0; i < this._pengCards.length; i++){
            if(this._pengCards[i] == jincard){
                player._stat.mingGangCount++;
            }
        }*/
        if(player._youjin || player._stat.roundPattern == Const.Pattern.SANJIN){
            player.setRoundResult(Const.Result.YJ);
        }
        if (this._stat.roundResult == MJ.Result.ZM) {
            this._stat.zmCount++;
        } else if (this._stat.roundResult == MJ.Result.DH) {
            this._stat.dhCount++;
            if (this._stat.roundTarget.length > 0) {
                var dpPlayer = this.getRoom().getPlayerByIndex(this._stat.roundTarget[0]);
                if (dpPlayer) {
                    dpPlayer._stat.dpCount++;
                }
            }
        }else {
            this._stat.failCount++;
        }


        for (var i = 0, l = this._gangCards.length; i < l; ++i) {
            var gangInfo = this._gangCards[i];
            if (gangInfo.type) {
                this._stat.anGangCount++;
            } else {
                if (gangInfo.gang == MJ.Gang.AN || gangInfo.gang == MJ.Gang.ANS) {
                    this._stat.anGangCount++;
                } else {
                    this._stat.mingGangCount++;
                }
            }
        }
        if (this.isDealer()) {
            this._stat.lzCount++;
        }
    },

    /******************************************************************
     * 重载的接口
     ******************************************************************/
    //断线重连信息
    getReconnectInfo: function(isSelf) {
        var info = this._super(isSelf);
        info.gangCards = this._gangCards;
        info.pengCards = this._pengCards;
        info.chiCards = this._chiCards;
        info.handCards = this._handCards.getCards();
        info.huaCards =  this._stat._huaCards;
        info.ftgd = this._ftgd;
        info.youJin = this._youjin;
        info.remainScore = this._stat.score;
        info.mai = this._selectMAI;
        return info;
    },

    getSettlementInfo: function() {
        var info = this._super();
        info.gangCards = this._gangCards;
        info.pengCards = this._pengCards;
        info.chiCards = this._chiCards;
        info.handCards = this._handCards.getCards();
        info.remainScore = this._stat.score;
        info.roundanGang = this._stat.roundanGang * 2;
        info.DianPao = this.isDianPao;
        info.gang = this._gangCards;
        info.mai = this._selectMAI;
        info.roundFan = this._roundFan;
        return info;
    },

    onStartNewRound: function() {
        this._super();
        this._selectMAI = -1;                //选择买不买-1/0/1 未选择/不买/买
        this.youjin = 0;                //游金
        this._youjin = false;
        this.isDianPao = false;
        this._selectCard = 0;

        this._stat._huaCards = [];           //花牌
        this._stat.bifan = 0;           //比番
        this._roundFan = 0;
        this._ftgd = [];
        this._stat.roundRules = {};
        this._stat.roundanGang = 0;        // 本轮暗杠次数
        this._stat.roundmingGang = 0;      // 本轮明杠次数
    },
    /*setBaoTing: function(){
        this._isBaoTing = true;
        var room = this.getRoom();
        room.curYouJin = true;
    },*/
    getInitHandCardNeedNum: function() {
        return (this.getIndex() != this.getRoom().getDealerIndex()) ? 16 : 17;
    },
    getInitHandCardPreCards: function() {
        var preCards = [];
        var room = this.getRoom();
        var distance = this.getRoom().getIndexDistance(this.getIndex(), this.getRoom().getDealerIndex());
        if (distance == 0) {

            /*preCards.push(42);
            preCards.push(43);
            preCards.push(44);
            preCards.push(45);
            preCards.push(46);
            preCards.push(47);
            preCards.push(48);
            preCards.push(16);
            preCards.push(16);*/


        } else if (distance == 1) {
            /*preCards.push(16);
            preCards.push(16);

            preCards.push(11);
            preCards.push(12);
            preCards.push(13);

            preCards.push(17);
            preCards.push(18);
            preCards.push(19);

            preCards.push(21);
            preCards.push(22);
            preCards.push(23);

            preCards.push(31);
            preCards.push(32);
            preCards.push(33);
            preCards.push(37);*/

        }

        return preCards;
    },
    playHua: function(hua){
        for(var i = 0; i < hua.length; i++){
            this._handCards.play(hua[i]);
            this._stat._huaCards.push(hua);
        }

    },
    gangCard: function(gangTask) {
        var selectGang = gangTask.selectGang || 0;
        if (selectGang > gangTask.gangArray.length) {
            selectGang = 0;
        }

        var selectGangTask = gangTask.gangArray[selectGang];

        if (selectGangTask.type) {
            return this._specGangCard(selectGangTask);
        } else {
            return this._super(selectGangTask);
        }
    },

    _getSpecGang: function(type) {
        var result = null;
        for (var i = 0, l = this._gangCards.length; i < l; ++i) {
            var gangInfo = this._gangCards[i];
            if (gangInfo.type == type) {
                result = gangInfo;
                break;
            }
        }
        return result;
    },

    _specGangCard: function(gangTask) {
        var gangInfo = null;

        this._handCards.dianGang(gangTask.card);

        gangInfo = clone(gangTask);
        delete gangInfo.playerIndex;
        this._gangCards.push(gangInfo);

        return gangInfo;
    },

    cancelLastGangForQG: function(card) {
        var gangIndex = this._gangCards.length - 1;
        if (gangIndex < 0) {
            return;
        }

        var gangInfo = this._gangCards[gangIndex];
        if (gangInfo.type) {
            if (gangInfo.buCard != card) {
                return;
            }

            if (gangInfo.buCards.length < 1) {
                return;
            }

            gangInfo.buCards.splice(gangInfo.buCards.length - 1, 1);
            gangInfo.buCard = (gangInfo.buCards.length > 0) ? gangInfo[gangInfo.buCards.length - 1] : 0;
        } else {
            return this._super(card);
        }
    },

    checkChiCondition: function(card) {
        var subConfig = this.getRoom().getSubConfig();
        var room = this.getRoom();
        var color = MJ.getColor(card);
        if (subConfig.colors.indexOf(color) == -1) {
            return false;
        }

        if (!MJ.isBasicColor(color)) {
            return false;
        }
        if(card == room.baoCard) {
            return false;
        }
        return true;
    },

    /*checkHuLogic: function(cards) {
        var pattern = MJ.Pattern.NORMAL;
        pattern = this.checkBaoHuLogic(cards);
        return pattern;
    },*/




    //检测碰牌
    checkPengWithCard: function(card) {

        if (this.getRoom().isSelectColor()) {
            if (MJ.getColor(card) == this.getSelectColor()) {
                return false;
            }
        }
        var room = this.getRoom();

        return this._handCards.getCardNum(card) >= 2;
    },
    //检查是否有花
    checkHua: function(){
        var hua = [];
        ExObject.eachKeyNum(this._handCards.getCards(), function(c, n) {
            if(MJ.getColor(c) == MJ.Color.HUA){
                hua.push(c);
            }
        });
        return hua;
    },
    //检测杠牌
    checkGang: function() {
        var room = this.getRoom();
        var gangArray = [];

        var lastCard = this._handCards.getLastNewCard();
        if (this.getIndex() != room.getCurPlay() || room.getCurTask()) {
            lastCard = 0;
        }
        if (lastCard != room.baoCard) { //优先杠刚摸上的牌
            if (this._handCards.getCardNum(lastCard) == 4) {
                    gangArray.push({card:lastCard, gang:MJ.Gang.AN});
            }
            if (this._pengCards.indexOf(lastCard) != -1) {
                gangArray.push({card:lastCard, gang:MJ.Gang.BA});
            }
            if(lastCard == room._jingCard){
                if (this._handCards.getCardNum(lastCard) == 3) {
                    gangArray.push({type: 5,card:lastCard, gang:5});
                }
            }
        }

        if (this._handCards.getCardNum(room._jingCard) == 3) {
            if(room._jingCard != lastCard)
                gangArray.push({type: 5,card:room._jingCard, gang:5});
        }

        var anGangCards = this._handCards.getAnGangCards();
        if (anGangCards.length > 0) {
            if (anGangCards[0] != lastCard) {
                if(anGangCards[0] != room.baoCard){
                    var gangInfo = {card:anGangCards[0], gang:MJ.Gang.ANS};
                    if (this.getRoom().getHideOption("anGangOverdue")) {
                        if (this.getPlayHand() != this.getRoom().getCurGang()) {
                            gangInfo.overdue = true;
                        }
                    }
                    gangArray.push(gangInfo);
                }
            }
        }

        this._pengCards.forEach(function(card) {
            if (this._handCards.getCardNum(card) > 0) {
                if (card != lastCard) {
                    gangArray.push({card: card, gang:MJ.Gang.BA, overdue: true});
                }
            }
        }.bind(this));

        var from = this.getIndex();
        gangArray.forEach(function(gangInfo) {
            gangInfo.from = from;
        });

        return gangArray;
    },

    checkHuNLogic: function(cards, huCard) {
        var num4 = 0;
        var num3 = 0;
        var num2 = 0;
        var num = 0;

        ExObject.each(cards, function(c, n) {
            if (n == 2) {
                num2++;
            } else if (n == 3) {
                num3++;
            } else if (n == 4) {
                num4++;
            }
            num += n;
        });

        if (num == 2 && this._chiCards.length <= 0) { // 碰碰胡
            return (num2 == 1) ? Const.Pattern.PAIR : MJ.Pattern.NONE;
        }
        var newCards = clone(cards);

        if ((num2 + num4*2) == 7) { // 七对
            return Const.Pattern.PAIR7;
        }
        if (num2 == 1 && ((num3*3 + 2) == num)  && this._chiCards.length <= 0) { // 碰碰胡
            return Const.Pattern.PAIR;
        }
        var room = this.getRoom();
        var colors = room.getSubConfig().colors;

        var pattern = MJ.Pattern.NORMAL;
        for (var i = 0, l = colors.length; i < l; ++i) {
            var color = colors[i];
            var colorCards = MJ.getColorCards(cards, color);

            if (MJ.isBasicColor(color)) {
                if (!MJ.checkHuColorCards(MJ.getValue(color, 1), MJ.getValue(color, MJ.COLOR_CARD_NUM), colorCards)) {
                    pattern = MJ.Pattern.NONE; break;
                }
            } else {
                var context = {
                    result: false,
                    hu3x2:false,
                    curbaocard:0
                };
                this.checkBaoPairColorCards(colorCards,context);
                if (!context.result) {
                    pattern = MJ.Pattern.NONE; break;
                }
            }
        }
        return pattern;
    },
    checkHuColorCards: function(minCard, maxCard, colorCards) {
        var colorCardsNum = MJ.sumCardsNum(colorCards);
        if (colorCardsNum == 0) {
            return true;
        }

        var context = {result: false};
        var modNum = colorCardsNum % 3;
        if (modNum == 0) {
            this.checkHu3X(minCard, maxCard, colorCards, context);
        } else if (modNum == 2) {
            this.checkHu3X2(minCard, maxCard, colorCards, context);
        }

        return context.result;
    },

    checkHu3X: function(minCard, maxCard, cards, context) {
        if (MJ.sumCardsNum(cards) < 1) {
            context.result = true;
            return;
        }

        for (var i = minCard; i <= maxCard; ++i) {
            var num = cards[i];
            if (!num) {
                continue;
            }

            var num2 = cards[i + 1];
            var num3 = cards[i + 2];

            if (num == 3) {
                if (num2 >= 3 && num3 >= 3) {
                    var newCards = clone(cards);
                    newCards[i] = 0;
                    newCards[i + 1] = num2 - 3;
                    newCards[i + 2] = num3 - 3;
                    this.checkHu3X(minCard, maxCard, newCards, context);
                }

                cards[i] = 0;
                this.checkHu3X(minCard, maxCard, cards, context);
            } else {
                if (num2 && num3) {
                    cards[i] = num - 1;
                    cards[i + 1] = num2 - 1;
                    cards[i + 2] = num3 - 1;
                    this.checkHu3X(minCard, maxCard, cards, context);
                }
            }
            break;
        }
    },

    checkHu3X2: function(minCard, maxCard, cards, context) {
        for (var i = minCard; i <= maxCard; ++i) {
            var num = cards[i];
            if (num >= 2) {
                var newCards = clone(cards);
                newCards[i] = num - 2;
                this.checkHu3X(minCard, maxCard, newCards, context);
                if (context.result) break;
            }
        }
    },

    checkPairHuColorCards: function(cards) {
        var num3 = 0;
        var num2 = 0;
        var numOther = 0;

        ExObject.each(cards, function(c, n) {
            if (n == 2) {
                num2++;
            } else if (n == 3) {
                num3++;
            } else {
                numOther++;
            }
        });

        if((numOther == 0) && (num2 <= 1)) {
            return true;
        }
        var context = {
            result: false,
            hu3x2:false,
            curbaocard:0
        };
        this.checkBaoPairColorCards(cards,context);
        return context.result;
    },
    //宝牌胡牌逻辑
    checkHuLogic:function(cards, huCard) {
        var room = this.getRoom();
        var baocard = cards[room.baoCard];
        if (!baocard) {
            baocard = 0;
        }
        var pattern = MJ.Pattern.NONE;
        var curBaocard = baocard;

        var colors = room.getSubConfig().colors;
        var hu3x2 = false;

        curBaocard = baocard;
        pattern = MJ.Pattern.NORMAL;

        //遍历每个花色

        for (var i = 0, l = colors.length; i < l; ++i) {
            var color = colors[i];
            var colorCards = MJ.getColorCards(cards, color);
            //如果颜色是宝牌颜色，去除宝牌再检测
            if (color == MJ.getColor(room.baoCard)) {
                colorCards[room.baoCard] = 0;
            }
            var colorCardsNum = MJ.sumCardsNum(colorCards);
            if (colorCardsNum == 0) {
                continue;
            }
            var context = {
                result: false,
                hu3x2: hu3x2,
                youjin: 0,
                curbaocard: curBaocard
            };
            if (MJ.isBasicColor(color)) {
                this.checkBaoColorCards(MJ.getValue(color, 1), MJ.getValue(color, MJ.COLOR_CARD_NUM), colorCards, context);
            } else {
                this.checkBaoPairColorCards(colorCards, context);
            }
            if (!context.result) {
                pattern = MJ.Pattern.NONE;
                break;
            }
            hu3x2 = context.hu3x2;
            curBaocard = context.curbaocard;
        }
        if (baocard >= 3) {//3个宝直接胡牌
            if(this.getIndex() == room.getCurPlay()){
                return Const.Pattern.SANJIN;
            }
        }
        /*if(this._stat._huaCards.length == 8){ //8张花牌胡？
            return Const.Pattern.EIGHTHUA;
        }*/
        return pattern;
    },

    //混调用3X
    checkColor3XCards: function(minCard, maxCard, cards, context){
        var colorCardsNum = MJ.sumCardsNum(cards);
        for(var bn = 0; bn <= context.curbaocard; bn++){
            var curbn = bn;
            var curmodNum = (colorCardsNum + curbn) % 3;
            if(curmodNum == 0){
                this.checkBaoHu3X(minCard, maxCard, cards, context, curbn);
                if (context.result) {
                    context.curbaocard -= curbn;
                    break;
                }
            }
        }
    },
    checkBaoColorCards: function(minCard, maxCard, cards, context){
        var colorCardsNum = MJ.sumCardsNum(cards);
        for(var bn = 0; bn <= context.curbaocard; bn++){
            var curbn = bn;
            var curmodNum = (colorCardsNum + curbn) % 3;
            if(curmodNum == 0){
                this.checkBaoHu3X(minCard, maxCard, cards, context, curbn);
                if (context.result) {
                    context.curbaocard -= curbn;
                    break;
                }
            } else if(curmodNum == 2 && !context.hu3x2){
                this.checkBaoHu3X2(minCard, maxCard, cards, context, curbn);
                if (context.result) {
                    context.curbaocard -= curbn;
                    context.hu3x2 = true;
                    break;
                }
            }
        }
    },
    checkBaoPairColorCards: function(cards, context) {
        var colorCardsNum = MJ.sumCardsNum(cards);
        for(var bn = 0; context.curbaocard >= bn; bn++){
            var curbn = bn;
            var curmodNum = (colorCardsNum + curbn) % 3;
            if(curmodNum == 0){
                context.result = this.checkBaoPairHuColorCards(cards, curbn);
                if (context.result) {
                    context.curbaocard -= curbn;
                    break;
                }
            } else if(curmodNum == 2 && !context.hu3x2){
                for (var i = 1; i <= 7; ++i) {
                    var num = cards[i];
                    if (num >= 2) {
                        var newCards = clone(cards);
                        newCards[i] = num - 2;
                        context.result = this.checkBaoPairHuColorCards(newCards, curbn);
                        if (context.result) {
                            break;
                        }
                    } else if(num == 1 && context.curbaocard) {
                        var newCards = clone(cards);
                        newCards[i] = 0;
                        curbn--;
                        context.result = this.checkBaoPairHuColorCards(newCards, curbn);
                        if (context.result) {
                            context.youjin = i;
                            break;
                        }
                    }
                }
                if (context.result) {
                    context.curbaocard -= curbn;
                    context.hu3x2 = true;
                    break;
                }
            }
            if(context.result) {
                break;
            }
        }
    },
    checkBaoHu3X: function(minCard, maxCard, cards, context, baocard) {
        var room = this.getRoom();
        var colorCardsNum = MJ.sumCardsNum(cards);
        if (colorCardsNum < 1) {
            context.result = true;
            return;
        }
        for (var i = minCard; i <= maxCard; ++i) {
            var num = cards[i];
            if (!num) {
                continue;
            }
            var num2 = cards[i + 1];
            var num3 = cards[i + 2];
            if (num == 3) {
                if (num2 > 0 && num3 > 0) {
                    var iTmp = 0;
                    if (num2 < 3) {
                        iTmp += 3 - num2;
                    }
                    if (num3 < 3) {
                        iTmp += 3 - num3;
                    }
                    if (iTmp <= baocard) {
                        var newCards = clone(cards);
                        var newbaocard = baocard;
                        newCards[i] = 0;
                        if (num2 >= 3) {
                            newCards[i + 1] = num2 - 3;
                        } else{
                            newbaocard -= 3 - newCards[i + 1];
                            newCards[i + 1] = 0;
                        }
                        if (num3 >= 3) {
                            newCards[i + 2] = num3 - 3;
                        } else {
                            newbaocard -= 3 - newCards[i + 2];
                            newCards[i + 2] = 0;
                        }
                        this.checkBaoHu3X(minCard, maxCard, newCards, context, newbaocard);
                    }
                }
                cards[i] = 0;
                this.checkBaoHu3X(minCard, maxCard, cards, context, baocard);
            } else if(num == 2){
                if (num2 > 0 && num3 > 0){
                    var iTmp = 0;
                    if (num2 < 2) {
                        iTmp += 2 - num2;
                    }
                    if (num3 < 2) {
                        iTmp += 2 - num3;
                    }
                    if (iTmp <= baocard) {
                        var newCards = clone(cards);
                        var newbaocard = baocard;
                        newCards[i] = 0;
                        if (num2 >= 2) {
                            newCards[i + 1] = num2 - 2;
                        } else{
                            newbaocard -= 2 - newCards[i + 1];
                            newCards[i + 1] = 0;
                        }
                        if (num3 >= 2) {
                            newCards[i + 2] = num3 - 2;
                        } else {
                            newbaocard -= 2 - newCards[i + 2];
                            newCards[i + 2] = 0;
                        }
                        this.checkBaoHu3X(minCard, maxCard, newCards, context, newbaocard);
                    }
                }
                if(baocard){
                    cards[i] = 0;
                    baocard--;
                    this.checkBaoHu3X(minCard, maxCard, cards, context, baocard);
                }
                if (((num2 || num3) && baocard) || (num2 && num3)) {
                    var newCards = clone(cards);
                    var newbaocard = baocard;
                    newCards[i] = num - 1;
                    if(num2) {
                        newCards[i + 1] = num2 - 1;
                    }else{
                        newbaocard--;
                    }
                    if(num3){
                        newCards[i + 2] = num3 - 1;
                    }
                    else{
                        newbaocard--;
                    }
                    this.checkBaoHu3X(minCard, maxCard, newCards, context, newbaocard);
                }
                if(num == 1 && baocard >= 2){
                    cards[i] = 0;
                    baocard -= 2;
                    this.checkBaoHu3X(minCard, maxCard, cards, context, baocard);
                }
            } else {
                if (((num2 || num3) && baocard) || (num2 && num3)) {
                    var newCards = clone(cards);
                    var newbaocard = baocard;
                    newCards[i] = num - 1;
                    if(num2) {
                        newCards[i + 1] = num2 - 1;
                    }else{
                        newbaocard--;
                    }
                    if(num3){
                        newCards[i + 2] = num3 - 1;
                    }
                    else{
                        newbaocard--;
                    }
                    this.checkBaoHu3X(minCard, maxCard, newCards, context, newbaocard);
                }
                if(num == 1 && baocard >= 2){
                    cards[i] = 0;
                    baocard -= 2;
                    this.checkBaoHu3X(minCard, maxCard, cards, context, baocard);
                }
            }
            break;
        }
    },

    checkBaoHu3X2: function(minCard, maxCard, cards, context, baocard) {
        var room = this.getRoom();
        for (var i = minCard; i <= maxCard; ++i) {
            var num = cards[i];

            if (num >= 2) {
                var newCards = clone(cards);
                newCards[i] = num - 2;

                var newBaocard = baocard;
                this.checkBaoHu3X(minCard, maxCard, newCards, context, newBaocard);
                if (context.result){
                    context.result = true;
                    break;
                }
            } else if(num == 1 && baocard) {
                var newCards = clone(cards);
                newCards[i] = 0;
                var newBaocard = baocard;
                newBaocard--;
                this.checkBaoHu3X(minCard, maxCard, newCards, context, newBaocard);
                if (context.result){
                    context.result = true;
                    context.youjin = i;
                    break;
                }
            }
        }
    },
    checkYouJing: function(cards){
        var room = this.getRoom();
        //var baoCard = cards[room.baoCard];
        //cards[room.baoCard] = 0;
        var player = this;
        var result = false;
        player.youjin = 0;
        ExObject.eachKeyNum(cards, function(c,n){
            if(result){
                return false;
            }
            var newCards = clone(cards);
            newCards[c] -= 1;
            var pattern = player.checkHuYouJing(newCards);
            if(pattern != MJ.Pattern.NONE){
                if(c != room.baoCard){
                    result = true;
                    player.youjin = c;
                }
            }
        });

        return result;
    },
    checkHuYouJing:function(cards){
        var room = this.getRoom();
        var baocard = cards[room.baoCard];
        if(!baocard){
            baocard = 0;
        }
        var pattern = MJ.Pattern.NONE;
        var curBaocard = baocard;
        var colors = room.getSubConfig().colors;
        var hu3x2 = false;
        curBaocard = baocard;
        pattern = MJ.Pattern.NORMAL;
        //遍历每个花色
        for (var i = 0, l = colors.length; i < l; ++i) {
            var color = colors[i];
            var colorCards = MJ.getColorCards(cards, color);
            //如果颜色是宝牌颜色，去除宝牌再检测
            if (color == MJ.getColor(room.baoCard)) {
                colorCards[room.baoCard] = 0;
            }
            var colorCardsNum = MJ.sumCardsNum(colorCards);
            if (colorCardsNum == 0) {
                continue;
            }
            var context = {
                result: false,
                hu3x2: hu3x2,
                youjin: 0,
                curbaocard:curBaocard
            };
            if (MJ.isBasicColor(color)) {
                this.checkBaoColorCards(MJ.getValue(color, 1), MJ.getValue(color, MJ.COLOR_CARD_NUM), colorCards, context);
            } else {
                this.checkBaoPairColorCards(colorCards, context);
            }
            if(!context.result){
                pattern = MJ.Pattern.NONE;
                break;
            }
            hu3x2 = context.hu3x2;
            curBaocard = context.curbaocard;
        }
        return pattern;
    },
    checkBaoPairHuColorCards: function(cards, baocard) {
        var num4 = 0;
        var num3 = 0;
        var num2 = 0;
        var numOther = 0;
        var colorCardsNum = MJ.sumCardsNum(cards);
        if (colorCardsNum < 1) {
            return true;
        }
        var newcard = baocard;
        ExObject.each(cards, function(c, n) {
            if(n == 1){
                if(newcard) {
                    newcard--;
                    num2++;
                }else{
                    numOther++;
                }
            }else if (n == 2) {
                if(newcard) {
                    newcard--;
                    num3++;
                }else{
                    num2++;
                }
            } else if (n == 3) {
                num3++;
            }else if (n == 0) {

            }else {
                numOther++;
            }
        });
        if((numOther == 0) && (num2 <= 1)) {
            return true;
        }
        return false;
        /*var context = {result: false};
        this.checkZiCard(cards, context, baocard);
        return context.result;*/
    },

    checkHunDiao:function(cards){
        var room = this.getRoom();
        var newCards = clone(cards);
        var baocard = cards[room.baoCard];

        if(baocard < 1){
            return false;
        }
        newCards[room.baoCard] -= 1;
        baocard -= 1;

        var curBaocard = baocard;

        //平胡
        var colors = room.getSubConfig().colors;
        var hu3x2 = false;
        curBaocard = baocard;
        var pattern = MJ.Pattern.NORMAL;
        //遍历每个花色
        for (var i = 0, l = colors.length; i < l; ++i) {
            var color = colors[i];
            var colorCards = MJ.getColorCards(newCards, color);
            //如果颜色是宝牌颜色，去除宝牌再检测
            if (color == MJ.getColor(room.baoCard)) {
                colorCards[room.baoCard] = 0;
            }
            var colorCardsNum = MJ.sumCardsNum(colorCards);
            if (colorCardsNum == 0) {
                continue;
            }
            var context = {
                result: false,
                hu3x2:true,
                curbaocard:curBaocard
            };

            if (MJ.isBasicColor(color)) {
                this.checkColor3XCards(MJ.getValue(color, 1), MJ.getValue(color, MJ.COLOR_CARD_NUM), colorCards, context);
            }else {
                MJ.checkBaoPairColorCards(colorCards, context);
            }
            if(!context.result){
                return false;
            }
            curBaocard = context.curbaocard;
        }
        return true;
    },
    /**
     * 是否可以胡13幺
     * @param cards
     */
    checkBaoHuOne13: function(cards) {
        var cardArr = Object.keys(cards);
        if (cardArr.length != 13) {
            return false;
        }

        return (cards[MJ.Value.TONG1] > 0) &&
            (cards[MJ.Value.TONG9] > 0) &&
            (cards[MJ.Value.TIAO1] > 0) &&
            (cards[MJ.Value.TIAO9] > 0) &&
            (cards[MJ.Value.WAN1] > 0) &&
            (cards[MJ.Value.WAN9] > 0) &&
            (cards[MJ.ZI.DF] > 0) &&
            (cards[MJ.ZI.NF] > 0) &&
            (cards[MJ.ZI.XF] > 0) &&
            (cards[MJ.ZI.BF] > 0) &&
            (cards[MJ.ZI.HZ] > 0) &&
            (cards[MJ.ZI.FC] > 0) &&
            (cards[MJ.ZI.BB] > 0);
    },

    checkBaoHuPair7: function(cards,baocard) {
        var num = 0;
        var room = this.getRoom();

        ExObject.eachKeyNum(cards, function(c, n) {
            if(c != room.baoCard){
                if (n == 2) {
                    num += 1;
                    cards[c] = 0;
                } else if (n == 4) {
                    num += 2;
                    cards[c] = 0;
                }else  if(n == 3){
                    num += 1;
                    cards[c] -= 2;
                }
            }
        });
        return (baocard >= 7 - num);
    },
    checkBaoHuBigPair: function(cards,baocard) {
        var num = 0;
        var num1 = 0;
        var num2 = 0;
        var num3 = 0;
        var num4 = 0;
        var card = baocard;
        var room = this.getRoom();
        ExObject.eachKeyNum(cards, function(c, n) {
            if(c != room.baoCard){
                if (n == 2) {
                    if(card){
                        card--;
                    }else{
                        num2++;
                    }
                } else if (n == 4) {
                    num4++;
                }else  if(n == 3){
                }else if(n == 1){
                    if(card){
                        card--;
                        num2++;
                    }else{
                        num1++;
                    }
                }
            }
            num++;
        });
        if(num2 == 2 && num1 == 0 && card > 0 && num4 == 0) {
            return true
        }else if(num1 == 1 && num2 == 0 && card > 0 && num4 == 0){
            return true
        }else if(num1 == 0 && num2 == 0 && num4 == 0) {
            return true;
        }else if(num2 == 1 && num1 == 0 && num4 == 0){
            return true;
        }
        return false
    },
    check13BuDa: function(cards,bao){
        var room = this.getRoom();
        var colors = room.getSubConfig().colors;
        var pattern = MJ.Pattern.NORMAL;
        var CardsNum = MJ.sumCardsNum(cards);
        if (CardsNum < 13) {
            return false;
        }
        if(bao) {
            cards[room.baoCard] = 0;
        }

        for (var i = 0, l = colors.length; i < l; ++i) {
            var color = colors[i];
            var minCard = MJ.getValue(color, 1);
            var maxCard = MJ.getValue(color, MJ.COLOR_CARD_NUM);
            var colorCards = MJ.getColorCards(cards, color);
            var colorCardsNum = MJ.sumCardsNum(colorCards);
            if (colorCardsNum < 1) {
               continue;
            }
            if (MJ.isBasicColor(color)) {
                if(!this.checkColorBuDa(minCard, maxCard, colorCards)){
                    return false;
                }
            } else {
                var num = true;
                ExObject.each(colorCards, function(c, n) {
                    if (n > 1) {
                        num = false;
                    }
                });
                if(!num){
                    return false;
                }
            }
        }
        return true;
    },
    checkColorBuDa:function(minCard, maxCard ,cards){
        for (var i = minCard; i <= maxCard; ++i) {
            var num = cards[i];
            if (!num) {
                continue;
            }
            if(num != 1){
                return false;
            }
            var num2 = cards[i + 1];
            var num3 = cards[i + 2];
            if(num2 || num3){
                return false;
            }
        }
        return true;
    },
});